package View.Town;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

import Model.Game;
import Model.Mule;
import Model.Player;
import Model.Store;
import Presenter.MainGameScreen;
import javax.swing.SwingConstants;

/**
 * Constructs the screen for the Store in the town
 * 
 * @author Emily
 * 
 */
public class StoreView extends JPanel {

	public JButton btnGoToTown;
	public Game g;
	public MainGameScreen gameScreen;
	public JButton buyOreBtn;
	public JButton sellOreBtn;
	public JLabel playerOreLbl;
	public JLabel storeOreLbl;
	public JLabel playerEnergyLbl;
	public JLabel storeEnergyLbl;
	public JLabel playerFoodLbl;
	public JLabel storeFoodLbl;
	
	public JLabel costOreLabel;
	public Player currentPlayer;
	private final int FOOD_STORE_PRICE = 30;
	private final int ENERGY_STORE_PRICE = 25;
	private final int ORE_STORE_PRICE = 50;
	private final JLabel warningLabel = new JLabel("");
	
	public JLabel playerMulesLbl;
	public JLabel storeMulesLbl;
	public JLabel costMulesLbl;
	public JButton buyMulesBtn;
	public JComboBox configureMule;



	/**
	 * Constructs the JComponents for the Store screen We need to pass in
	 * gameScreen and game so as to set player attributes on purchases. (You can
	 * see PubView for how this works)
	 */
	public StoreView(final Game g, final MainGameScreen gameScreen) {

		final Store store = g.getStore();
		currentPlayer = g.getPlayers()[gameScreen.getRound().getTurn().getCurrentPlayer()];
		this.g = g;
		this.gameScreen = gameScreen;

		setBackground(Color.BLACK);
		setLayout(null);
		setPreferredSize(new Dimension(1200, 800));

		JPanel orepanel = new JPanel();
		orepanel.setBounds(111, 183, 976, 112);
		add(orepanel);
		orepanel.setLayout(null);

		JLabel oreLabel = new JLabel("ORE");
		oreLabel.setBounds(44, 42, 91, 36);
		orepanel.add(oreLabel);
		oreLabel.setFont(new Font("Helvetica", Font.PLAIN, 30));
		oreLabel.setForeground(new Color(204, 153, 0));

		buyOreBtn = new JButton("BUY");
		buyOreBtn.setBounds(449, 25, 75, 29);
		orepanel.add(buyOreBtn);

		sellOreBtn = new JButton("SELL");
		sellOreBtn.setBounds(449, 53, 75, 29);
		orepanel.add(sellOreBtn);

		playerOreLbl = new JLabel(Integer.toString(currentPlayer.getOre()));
		playerOreLbl.setForeground(new Color(204, 153, 0));
		playerOreLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		playerOreLbl.setBounds(256, 25, 91, 57);
		orepanel.add(playerOreLbl);

		storeOreLbl = new JLabel(Integer.toString(g.getStore().getOre()));
		storeOreLbl.setForeground(new Color(204, 153, 0));
		storeOreLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		storeOreLbl.setBounds(663, 25, 91, 57);
		orepanel.add(storeOreLbl);

		costOreLabel = new JLabel(Integer.toString(ORE_STORE_PRICE));
		costOreLabel.setForeground(new Color(204, 153, 0));
		costOreLabel.setFont(new Font("Helvetica", Font.PLAIN, 59));
		costOreLabel.setBounds(860, 25, 91, 57);
		orepanel.add(costOreLabel);
		sellOreBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (buyResource(currentPlayer, "ORE")) {
					changeLabels(currentPlayer, "ORE");
				}
			}
		});
		buyOreBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (sellResource(currentPlayer, "ORE")) {
					changeLabels(currentPlayer, "ORE");
				}
			}
		});

		JPanel energypanel = new JPanel();
		energypanel.setLayout(null);
		energypanel.setBounds(111, 307, 976, 112);
		add(energypanel);

		JLabel energyLabel = new JLabel("ENERGY");
		energyLabel.setForeground(new Color(204, 153, 0));
		energyLabel.setFont(new Font("Helvetica", Font.PLAIN, 30));
		energyLabel.setBounds(44, 42, 141, 36);
		energypanel.add(energyLabel);

		JButton button = new JButton("BUY");
		button.setBounds(449, 25, 75, 29);
		energypanel.add(button);

		JButton button_1 = new JButton("SELL");
		button_1.setBounds(449, 53, 75, 29);
		energypanel.add(button_1);

		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (buyResource(currentPlayer, "ENERGY")) {
					changeLabels(currentPlayer, "ENERGY");
				}
			}
		});
		button_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (sellResource(currentPlayer, "ENERGY")) {
					changeLabels(currentPlayer, "ENERGY");
				}
			}
		});

		playerEnergyLbl = new JLabel(Integer.toString(currentPlayer.getEnergy()));
		playerEnergyLbl.setForeground(new Color(204, 153, 0));
		playerEnergyLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		playerEnergyLbl.setBounds(255, 25, 91, 57);
		energypanel.add(playerEnergyLbl);

		storeEnergyLbl = new JLabel(Integer.toString(g.getStore().getEnergy()));
		storeEnergyLbl.setForeground(new Color(204, 153, 0));
		storeEnergyLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		storeEnergyLbl.setBounds(663, 25, 91, 57);
		energypanel.add(storeEnergyLbl);

		JLabel costEnergyLbl = new JLabel(Integer.toString(ENERGY_STORE_PRICE));
		costEnergyLbl.setForeground(new Color(204, 153, 0));
		costEnergyLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		costEnergyLbl.setBounds(860, 25, 91, 57);
		energypanel.add(costEnergyLbl);

		JPanel foodPanel = new JPanel();
		foodPanel.setLayout(null);
		foodPanel.setBounds(111, 432, 976, 112);
		add(foodPanel);

		JLabel foodLabel = new JLabel("FOOD");
		foodLabel.setForeground(new Color(204, 153, 0));
		foodLabel.setFont(new Font("Helvetica", Font.PLAIN, 30));
		foodLabel.setBounds(44, 42, 91, 36);
		foodPanel.add(foodLabel);

		JButton buyFoodBtn = new JButton("BUY");
		buyFoodBtn.setBounds(449, 25, 75, 29);
		foodPanel.add(buyFoodBtn);

		JButton sellFoodBtn = new JButton("SELL");
		sellFoodBtn.setBounds(449, 53, 75, 29);
		foodPanel.add(sellFoodBtn);

		sellFoodBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (sellResource(currentPlayer, "FOOD")) {
					changeLabels(currentPlayer, "FOOD");
				}
			}
		});
		buyFoodBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (buyResource(currentPlayer, "FOOD")) {
					changeLabels(currentPlayer, "FOOD");
				}
			}
		});

		playerFoodLbl = new JLabel(Integer.toString(currentPlayer.getFood()));
		playerFoodLbl.setForeground(new Color(204, 153, 0));
		playerFoodLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		playerFoodLbl.setBounds(255, 25, 91, 57);
		foodPanel.add(playerFoodLbl);

		storeFoodLbl = new JLabel(Integer.toString(g.getStore().getFood()));
		storeFoodLbl.setForeground(new Color(204, 153, 0));
		storeFoodLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		storeFoodLbl.setBounds(663, 25, 91, 57);
		foodPanel.add(storeFoodLbl);

		JLabel costFoodLbl = new JLabel(Integer.toString(FOOD_STORE_PRICE));
		costFoodLbl.setForeground(new Color(204, 153, 0));
		costFoodLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		costFoodLbl.setBounds(860, 25, 91, 57);
		foodPanel.add(costFoodLbl);

		JPanel mulePanel = new JPanel();
		mulePanel.setLayout(null);
		mulePanel.setBounds(111, 556, 976, 116);
		add(mulePanel);

		JLabel muleLabel = new JLabel("MULES");
		muleLabel.setForeground(new Color(204, 153, 0));
		muleLabel.setFont(new Font("Helvetica", Font.PLAIN, 30));
		muleLabel.setBounds(44, 42, 115, 36);
		mulePanel.add(muleLabel);

		playerMulesLbl = new JLabel( currentPlayer.stringGetPossessMule() );
		playerMulesLbl.setForeground(new Color(204, 153, 0));
		playerMulesLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		playerMulesLbl.setBounds(255, 25, 83, 57);
		mulePanel.add(playerMulesLbl);

		storeMulesLbl = new JLabel(Integer.toString(store.getMules())); // store supply
		storeMulesLbl.setForeground(new Color(204, 153, 0));
		storeMulesLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		storeMulesLbl.setBounds(663, 25, 91, 57);
		mulePanel.add(storeMulesLbl);

		costMulesLbl = new JLabel("150");
		costMulesLbl.setForeground(new Color(204, 153, 0));
		costMulesLbl.setFont(new Font("Helvetica", Font.PLAIN, 59));
		costMulesLbl.setBounds(831, 25, 109, 57);
		mulePanel.add(costMulesLbl);

		buyMulesBtn = new JButton("BUY");
		buyMulesBtn.setBounds(449, 6, 75, 29);
		mulePanel.add(buyMulesBtn);

		// warning label
		warningLabel.setBounds(200, 33, 799, 36);
		warningLabel.setForeground(Color.RED);
		warningLabel.setFont(new Font("Helvetica", Font.PLAIN, 30));
		add(warningLabel);
		warningLabel.setVisible(true);
		
		// Add comboBox with mule configuration types
		String[] muleTypes = { "Energy", "Food", "Smithore" };
		configureMule = new JComboBox(muleTypes);
		configureMule.setBounds(436, 41, 115, 27);
		mulePanel.add(configureMule);
		configureMule.addActionListener(new ActionListener() {

			// Action listener to update cost label
			public void actionPerformed(ActionEvent e) {
				// Instantiate desired mule
				Mule desiredMule = new Mule((String) configureMule.getSelectedItem());

				// set cost label
				costMulesLbl.setText(Integer.toString(desiredMule.getCost()));
			}
		});

		buyMulesBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				// get the currentPlayer so we can properly set his data later
				int currentPlayerNum = gameScreen.getRound().getTurn().getCurrentPlayer();
				final Player currentPlayer = g.getPlayers()[currentPlayerNum];

				// instantiate mule with configuration
				Mule desiredMule = new Mule((String) configureMule.getSelectedItem());

				// check sufficient funds and give mule to player
				if (currentPlayer.sufficientFunds(desiredMule.getCost()) && store.sufficientMules()) 
				{
					
					// give mule to player and subtract cost
					currentPlayer.setMule(desiredMule);
					currentPlayer.setPossessMule(true);
					currentPlayer.subtractMoney(desiredMule.getCost());

					// update store inventory
					store.decrementMules();

					//disable buying
					buyMulesBtn.setEnabled(false);
					configureMule.setEnabled(false);

					// update labels
					playerMulesLbl.setText("1");
					storeMulesLbl.setText(Integer.toString(store.getMules()));
					warningLabel.setText("");
					updatePlayerInfo();

				}

				// Store is out of mules label
				else if (!store.sufficientMules()) {
					warningLabel.setText("THE STORE IS OUT OF MULES");

				}

				// Player has insufficient funds label
				else {
					warningLabel.setText("YOU HAVE INSUFFICIENT FUNDS");
				}

			}
		});

		JLabel playerMoneyLbl = new JLabel("YOUR MONEY:");
		playerMoneyLbl.setFont(new Font("Helvetica", Font.PLAIN, 40));
		playerMoneyLbl.setForeground(new Color(204, 153, 0));
		playerMoneyLbl.setBounds(87, 709, 335, 52);
		add(playerMoneyLbl);

		JLabel labelStore = new JLabel("STORE");
		labelStore.setHorizontalAlignment(SwingConstants.CENTER);
		labelStore.setFont(new Font("Helvetica", Font.PLAIN, 50));
		labelStore.setForeground(Color.WHITE);
		labelStore.setBounds(490, 83, 219, 79);
		add(labelStore);

		JLabel lblYouHave = new JLabel("YOU HAVE:");
		lblYouHave.setForeground(new Color(204, 153, 0));
		lblYouHave.setFont(new Font("Helvetica", Font.PLAIN, 30));
		lblYouHave.setBounds(291, 134, 203, 57);
		add(lblYouHave);

		JLabel lblStoreHas = new JLabel("STORE HAS:");
		lblStoreHas.setForeground(new Color(204, 153, 0));
		lblStoreHas.setFont(new Font("Helvetica", Font.PLAIN, 30));
		lblStoreHas.setBounds(698, 134, 197, 57);
		add(lblStoreHas);

		JLabel lblCost = new JLabel("COST");
		lblCost.setForeground(new Color(204, 153, 0));
		lblCost.setFont(new Font("Helvetica", Font.PLAIN, 30));
		lblCost.setBounds(958, 134, 117, 57);
		add(lblCost);
		
		btnGoToTown = new JButton("BACK TO TOWN");
		btnGoToTown.setBounds(909, 6, 285, 97);
		add(btnGoToTown);
	}

	/**
	 * Buys a resource for the current player. Does not buy a resource if the store is out
	 * or if the player has insufficient funds.
	 * @param currentPlayer
	 * @param resource
	 * @return true if resource was purchased successfully, false if there was some impediment
	 */
	public boolean buyResource(Player currentPlayer, String resource) {
		if (resource == "ORE") {
			if (currentPlayer.getMoney() >= ORE_STORE_PRICE
					&& g.getStore().getOre() > 0) {
				warningLabel.setText("");
				currentPlayer.setOre(currentPlayer.getOre() + 1);
				g.getStore().setOre(g.getStore().getOre() - 1);
				currentPlayer.setMoney(currentPlayer.getMoney()
						- ORE_STORE_PRICE);
				System.out.println("bought ore");
				System.out.println("You have $" +currentPlayer.getMoney());
				updatePlayerInfo();
				return true;
			}
			else {
				warningLabel.setText((!(currentPlayer.getMoney() >= ORE_STORE_PRICE))?"INSUFFICIENT FUNDS":"THE STORE DOESN'T HAVE ENOUGH MERCHANDISE");
				return false;
			}
		} else if (resource == "ENERGY") {
			if (currentPlayer.getMoney() >= ENERGY_STORE_PRICE
					&& g.getStore().getEnergy() > 0) {
				warningLabel.setText("");
				currentPlayer.setEnergy(currentPlayer.getEnergy() + 1);
				g.getStore().setEnergy(g.getStore().getEnergy() - 1);
				currentPlayer.setMoney(currentPlayer.getMoney()
						- ENERGY_STORE_PRICE);
				System.out.println("bought energy");
				System.out.println("You have $" +currentPlayer.getMoney());
				updatePlayerInfo();
				return true;
			} else {
				warningLabel.setText((!(currentPlayer.getMoney() >= ORE_STORE_PRICE))?"INSUFFICIENT FUNDS":"THE STORE DOESN'T HAVE ENOUGH MERCHANDISE");
				return false;
			}

		} else {
			if (currentPlayer.getMoney() >= FOOD_STORE_PRICE
					&& g.getStore().getFood() > 0) {
				warningLabel.setText("");
				currentPlayer.setFood(currentPlayer.getFood() + 1);
				g.getStore().setFood(g.getStore().getFood() - 1);
				currentPlayer.setMoney(currentPlayer.getMoney()
						- FOOD_STORE_PRICE);
				System.out.println("bought food");
				System.out.println("You have $" +currentPlayer.getMoney());
				updatePlayerInfo();
				return true;
			} else {
				warningLabel.setText((!(currentPlayer.getMoney() >= ORE_STORE_PRICE))?"INSUFFICIENT FUNDS":"THE STORE DOESN'T HAVE ENOUGH MERCHANDISE");
				return false;
			}
		}
	}

	/**
	 * Sells a resource from the current player to the store. Does not sell a resource if the player is out
	 * of that resource.
	 * @param currentPlayer
	 * @param resource
	 * @return true if resource was sold successfully, false if there was some impediment
	 */
	public boolean sellResource(Player currentPlayer, String resource) {
		if (resource == "ORE") {
			if (currentPlayer.getOre() > 0) {
				warningLabel.setText("");
				currentPlayer.setOre(currentPlayer.getOre() - 1);
				g.getStore().setOre(g.getStore().getOre() + 1);
				currentPlayer.setMoney(currentPlayer.getMoney()
						+ ORE_STORE_PRICE);
				System.out.println("sold ore");
				System.out.println("You have $" +currentPlayer.getMoney());
				updatePlayerInfo();
				return true;
			} else {
				warningLabel.setText("YOU DON'T HAVE ENOUGH MERCHANDISE");
				return false;
			}
		} else if (resource == "ENERGY") {
			if (currentPlayer.getEnergy() > 0) {
				warningLabel.setText("");
				currentPlayer.setEnergy(currentPlayer.getEnergy() - 1);
				g.getStore().setEnergy(g.getStore().getEnergy() + 1);
				currentPlayer.setMoney(currentPlayer.getMoney()
						+ ENERGY_STORE_PRICE);
				System.out.println("sold energy");
				System.out.println("You have $" +currentPlayer.getMoney());
				updatePlayerInfo();
				return true;
			} else {
				warningLabel.setText("YOU DON'T HAVE ENOUGH MERCHANDISE");
				return false;
			}

		} else {
			if (currentPlayer.getFood() > 0) {
				warningLabel.setText("");
				currentPlayer.setFood(currentPlayer.getFood() - 1);
				g.getStore().setFood(g.getStore().getFood() + 1);
				currentPlayer.setMoney(currentPlayer.getMoney()
						+ FOOD_STORE_PRICE);
				System.out.println("sold food");
				System.out.println("You have $" +currentPlayer.getMoney());
				updatePlayerInfo();
				return true;
			} else {
				warningLabel.setText("YOU DON'T HAVE ENOUGH MERCHANDISE");
				return false;
			}
		}
	}

	/**
	 * Changes the screen labels for the bought or sold resource
	 * @param currentPlayer
	 * @param resource
	 */
	public void changeLabels(Player currentPlayer, String resource) {
		if (resource.equals("ORE")) {
			playerOreLbl.setText(Integer.toString(currentPlayer.getOre()));
			storeOreLbl.setText(Integer.toString(g.getStore().getOre()));
		} else if (resource.equals("ENERGY")){
			playerEnergyLbl.setText(Integer.toString(currentPlayer.getEnergy()));
			storeEnergyLbl.setText(Integer.toString(g.getStore().getEnergy()));
		} else {
			playerFoodLbl.setText(Integer.toString(currentPlayer.getFood()));
			storeFoodLbl.setText(Integer.toString(g.getStore().getFood()));
		}
	}
	
	/**
	 * Updates the player name and money amount in the infopanel.
	 */
	public void updatePlayerInfo()
	{
		gameScreen.updatePlayer(currentPlayer.getName());
		gameScreen.updateMoney(currentPlayer.getMoney());
	}
}
